#include "thread_pool.h"

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

// 任务队列结构
typedef struct {
    task_t *tasks;  // 任务数组
    int front;      // 队头
    int rear;       // 队尾
    int size;       // 当前任务数
    int capacity;   // 队列容量
} queue_t;

// 初始化任务队列
queue_t* queue_init(int capacity) {
    queue_t *q = (queue_t *)malloc(sizeof(queue_t));
    q->tasks = (task_t *)malloc(sizeof(task_t) * capacity);
    q->front = q->rear = q->size = 0;
    q->capacity = capacity;
    return q;
}

// 销毁任务队列
void queue_destroy(queue_t *q) {
    free(q->tasks);
    free(q);
}

// 判断队列是否为空
int queue_is_empty(queue_t *q) {
    return q->size == 0;
}

// 判断队列是否已满
int queue_is_full(queue_t *q) {
    return q->size == q->capacity;
}

// 添加任务到队列
int queue_push(queue_t *q, task_t task) {
    if (queue_is_full(q)) {
        return -1; // 队列已满
    }
    q->tasks[q->rear] = task;
    q->rear = (q->rear + 1) % q->capacity;
    q->size++;
    return 0;
}

// 从队列中取出任务
int queue_pop(queue_t *q, task_t *task) {
    if (queue_is_empty(q)) {
        return -1; // 队列为空
    }
    *task = q->tasks[q->front];
    q->front = (q->front + 1) % q->capacity;
    q->size--;
    return 0;
}

// 工作线程函数
void* worker_thread(void *arg) {
    thrpool_t *pool = (thrpool_t *)arg;
    task_t task;

    while (1) {
        pthread_mutex_lock(&pool->pool_mut);

        // 如果线程池关闭，退出线程
        if (pool->shutdown) {
            pthread_mutex_unlock(&pool->pool_mut);
            break;
        }

        // 如果exit_cnt > 0，减少线程数
        if (pool->exit_cnt > 0) {
            pool->exit_cnt--;
            pool->alive_cnt--;
            pthread_mutex_unlock(&pool->pool_mut);
            break;
        }

        // 如果任务队列为空，等待任务
        while (queue_is_empty(pool->task_queue)) {
            pthread_cond_wait(&pool->task_cond_not_empty, &pool->pool_mut);
        }

        // 取出任务
        queue_pop(pool->task_queue, &task);
        pthread_cond_signal(&pool->task_cond_not_full);

        pthread_mutex_unlock(&pool->pool_mut);

        // 执行任务
        pthread_mutex_lock(&pool->busy_mut);
        pool->busy_cnt++;
        pthread_mutex_unlock(&pool->busy_mut);

        task.thr_task_p(task.arg);

        pthread_mutex_lock(&pool->busy_mut);
        pool->busy_cnt--;
        pthread_mutex_unlock(&pool->busy_mut);
    }

    pthread_exit(NULL);
}

// 管理者线程函数
void* admin_thread(void *arg) {
    thrpool_t *pool = (thrpool_t *)arg;

    while (!pool->shutdown) {
        sleep(1); // 每隔1秒检查一次

        pthread_mutex_lock(&pool->pool_mut);
        int queue_size = pool->task_queue->size;
        int alive_cnt = pool->alive_cnt;
        int busy_cnt = pool->busy_cnt;
        pthread_mutex_unlock(&pool->pool_mut);

        // 根据任务队列大小和忙碌线程数调整线程池大小
        if (queue_size > alive_cnt && alive_cnt < pool->thrs_max_cnt) {
            // 创建新线程
            pthread_t tid;
            pthread_create(&tid, NULL, worker_thread, pool);
            pthread_detach(tid);
            pthread_mutex_lock(&pool->pool_mut);
            pool->alive_cnt++;
            pthread_mutex_unlock(&pool->pool_mut);
        }

        if (busy_cnt * 2 < alive_cnt && alive_cnt > pool->thrs_min_cnt) {
            // 减少线程
            pthread_mutex_lock(&pool->pool_mut);
            pool->exit_cnt++;
            pthread_mutex_unlock(&pool->pool_mut);
        }
    }

    pthread_exit(NULL);
}

// 初始化线程池
int thread_pool_init(thrpool_t **mypool, int min_cnt, int max_cnt) {
    if (min_cnt < 1 || max_cnt > THR_MAX || min_cnt > max_cnt) {
        return -1;
    }

    thrpool_t *pool = (thrpool_t *)malloc(sizeof(thrpool_t));
    pool->workers = (pthread_t *)malloc(sizeof(pthread_t) * max_cnt);
    pool->task_queue = queue_init(max_cnt);

    pthread_mutex_init(&pool->pool_mut, NULL);
    pthread_cond_init(&pool->task_cond_not_empty, NULL);
    pthread_cond_init(&pool->task_cond_not_full, NULL);
    pthread_mutex_init(&pool->busy_mut, NULL);

    pool->alive_cnt = min_cnt;
    pool->busy_cnt = 0;
    pool->exit_cnt = 0;
    pool->shutdown = 0;
    pool->thrs_min_cnt = min_cnt;
    pool->thrs_max_cnt = max_cnt;

    // 创建工作线程
    for (int i = 0; i < min_cnt; i++) {
        pthread_create(&pool->workers[i], NULL, worker_thread, pool);
        pthread_detach(pool->workers[i]);
    }

    // 创建管理者线程
    pthread_create(&pool->admin_tid, NULL, admin_thread, pool);

    *mypool = pool;
    return 0;
}

// 添加任务到线程池
int thread_pool_add_task(thrpool_t *mypool, const task_t *mytask) {
    pthread_mutex_lock(&mypool->pool_mut);

    // 如果任务队列已满，等待
    while (queue_is_full(mypool->task_queue)) {
        pthread_cond_wait(&mypool->task_cond_not_full, &mypool->pool_mut);
    }

    // 添加任务
    queue_push(mypool->task_queue, *mytask);
    pthread_cond_signal(&mypool->task_cond_not_empty);

    pthread_mutex_unlock(&mypool->pool_mut);
    return 0;
}

// 销毁线程池
void thread_pool_destroy(thrpool_t **mypool) {
    thrpool_t *pool = *mypool;

    pthread_mutex_lock(&pool->pool_mut);
    pool->shutdown = 1;
    pthread_mutex_unlock(&pool->pool_mut);

    // 唤醒所有工作线程
    pthread_cond_broadcast(&pool->task_cond_not_empty);

    // 等待管理者线程退出
    pthread_join(pool->admin_tid, NULL);

    // 销毁任务队列
    queue_destroy(pool->task_queue);

    // 销毁互斥量和条件变量
    pthread_mutex_destroy(&pool->pool_mut);
    pthread_cond_destroy(&pool->task_cond_not_empty);
    pthread_cond_destroy(&pool->task_cond_not_full);
    pthread_mutex_destroy(&pool->busy_mut);

    // 释放内存
    free(pool->workers);
    free(pool);

    *mypool = NULL;
}